#region LGPL License
//
//Adriano Ribeiro <adribeiro@gmail.com>
//
//Copyright (c) 2007 Mono Overlay Routing Foundation Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


#endregion


using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace Monorf.Net
{
    /// <summary>
    /// Description of BasicProtocolListener.
    /// </summary>
    public class BaseListener<CommunicationData>: IListener<CommunicationData> where CommunicationData: new()
    {
        protected NetworkBuffer m_messageBuffer;
        protected Handle m_handleListener;
        protected AsyncCallback m_receiveCompletion;
        protected WaitCallback m_dataReceiveDispatch;
        protected WaitCallback m_continousListen;
        protected IPEndPoint m_listenEndPoint;
        protected static Object m_lockObject = new Object();
        protected Boolean m_isActive = false;
        protected Boolean m_stop = false;
        protected CommunicationLink<CommunicationData> m_communicationData = null;

        public BaseListener(Int32 messageSize, CommunicationLink<CommunicationData> communicationData, 
                            Handle handleListener)
        {
            m_handleListener = handleListener;
            m_messageBuffer = new NetworkBuffer(messageSize);
            m_receiveCompletion = new AsyncCallback(AcceptCompleteCallBack);
            m_communicationData = communicationData;
        }


        //protected virtual void CreateSocket() { }

        /// <summary>
        /// start listening
        /// </summary>
        public virtual void Listen()
        {
            //create socket to listen using another thread, i used this to allow
            // in future listen multiple sockets
            //CreateSocket();

            //start to listen in another thread
            m_continousListen = new WaitCallback(BeginAccept);
            ThreadPool.QueueUserWorkItem(m_continousListen, m_handleListener);
        }

        public virtual void Close()
        {
            m_stop = true;
        }

        public virtual void BeginAccept(Object state) { }

        /// <summary>
        /// post received data to next layer
        /// </summary>
        /// <param name="state"></param>
        public virtual void EndAccept(CommunicationData state) 
        {
            if(!m_stop)
                m_communicationData.PostData(state);
        }

        //protected void ContinousListening(Object state)
        //{
        //    this.BeginReceive(state, m_receiveCompletion);
        //}

        protected virtual void AcceptCompleteCallBack(IAsyncResult result) { }

    }
}
